<?php
namespace soa\check\waybill;


class Check extends Rule
{
    public function __construct($brand, $data = [])
    {
        parent::__construct($brand, $data);
    }

    private function init($waybillNo)
    {
        if(!isset($this->availableBrand[$this->brand])) {
            return false;
        }
        if(empty($this->rule)){
            $this->rule = $this->getRule();
        }
    }

    /**
     * 验证普通运单号规则
     *
     * @param $waybillNo
     * @return bool
     */
    public function checkGeneralRule($waybillNo)
    {
        $this->init($waybillNo);

        $rules = !empty($this->rule['generalRule']) ? $this->rule['generalRule'] : '';
        if($this->brand == 'sto'){
            foreach($this->stoRule['order'] as $type=>$rules){
                if(preg_match($rules,$waybillNo)) {
                    return true;
                }
            }
            foreach($this->stoRule['verify'] as $type => $rules){
                if(preg_match($rules, $waybillNo)) {
                    return $this->chkStoValidCode($waybillNo);
                }
            }
            foreach($this->stoRule['free'] as $type => $rules){
                if(preg_match($rules, $waybillNo)) {
                    return true;
                }
            }
            return false;
        }else{
            $status = $this->runPreg('/'.$rules.'/', $waybillNo);
        }

        return $status;
    }

    /**
     * 验证电子面单规则
     *
     * @param $waybillNo
     * @return bool
     */
    public function checkThermalRule($waybillNo)
    {
        $this->init($waybillNo);
        $rules = !empty($this->rule['thermalRule']) ? $this->rule['thermalRule'] : '';
        return $this->runPreg('/'.$rules.'/', $waybillNo);
    }

    /**
     * 执行正则匹配验证方法
     *
     * @param $rule
     * @param $waybillNo
     * @return bool
     */
    public function runPreg($rule,$waybillNo)
    {
        if(preg_match($rule, $waybillNo)){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 验证13位单号的最后一位校验码
     *
     * @param $num
     * @return bool
     */
    public function chkStoValidCode($num)
    {
        if(strlen($num) != 13){
            return TRUE;
        }
        $val = substr($num, 3, 9);
        $v = $val[0]*7;
        $v += $val[1]*9;
        $v += $val[2]*5;
        $v += $val[3]*3;
        $v += $val[4]*2;
        $v += $val[5]*4;
        $v += $val[6]*6;
        $v += $val[7]*8;
        $v += $val[8]*9;
        $remainder = $v%11;
        switch($remainder){
            case 0:
                $validCode = 5;
                break;
            case 1:
                $validCode = 0;
                break;
            default:
                $validCode = 11-$remainder;
        }
        return $validCode == substr($num, 12, 1) ? TRUE : FALSE;
    }

}